package com.wudizaba.microservicesdemosystem.util;


import cn.hutool.core.convert.Convert;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.read.metadata.ReadSheet;
import com.wudizaba.microservicesdemocommon.Exceptions.ExcelException;
import com.wudizaba.microservicesdemocommon.constant.ExceptionsConstant;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Collection;
import java.util.List;

/**
 * excel工具类
 *
 * @author wudizaba
 * 2024-06-14 10:10:10
 */
@Slf4j
public class ExcelUtil {

    public static String getBase64(Class<?> head, String sheetName, Collection<?> data) {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        EasyExcel.write(outputStream, head)
                .sheet(sheetName)
                .doWrite(data);
        return Base64.getEncoder().encodeToString(outputStream.toByteArray());
    }

    public static void write(ServletOutputStream outputStream, Class<?> head, String sheetName, Collection<?> data) {
        EasyExcel.write(outputStream, head)
                .sheet(sheetName)
                .doWrite(data);
    }

    public static void write(HttpServletResponse response, Class<?> clazz, String fileName, String sheetName, Collection<?> data) {
        OutputStream outputStream = null;
        try {
            outputStream = getOutputStream(response, fileName);
        } catch (IOException e) {
            throw new ExcelException(ExceptionsConstant.EXCEL_EXPORT_ERROR);
        }

        EasyExcel.write(outputStream, clazz)
                .sheet(sheetName)
                .doWrite(data);

        try {
            outputStream.flush();
            outputStream.close();
        } catch (IOException e) {
            throw new ExcelException(ExceptionsConstant.EXCEL_EXPORT_ERROR);
        }
    }

    private static OutputStream getOutputStream(HttpServletResponse response, String fileName) throws IOException {
        fileName = URLEncoder.encode(fileName, "UTF-8");
        response.setContentType("application/octet-stream;charset=UTF-8");
        response.setCharacterEncoding("utf-8");
        response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
        log.info("文件名：{}", fileName);
        return response.getOutputStream();
    }


    /**
     * 读取Excel（多个sheet可以用同一个实体类解析）
     *
     * @param excelInputStream 输入流
     * @param fileName         文件名
     * @param clazz            实体类
     * @return
     */
    public static <T> List<T> readExcel(InputStream excelInputStream, String fileName, Class<T> clazz) {
        ExcelListener excelListener = new ExcelListener();
        ExcelReader excelReader = getReader(excelInputStream, fileName, clazz, excelListener);
        if (excelReader == null) {
            return new ArrayList<>();
        }
        List<ReadSheet> readSheetList = excelReader.excelExecutor().sheetList();
        for (ReadSheet readSheet : readSheetList) {
            excelReader.read(readSheet);
        }
        excelReader.finish();
        return Convert.toList(clazz, excelListener.getDataList());
    }

    private static <T> ExcelReader getReader(InputStream inputStream, String fileName, Class<T> clazz, ExcelListener excelListener) {
        try {
            if (fileName == null ||
                    (!fileName.toLowerCase().endsWith(".xls") && !fileName.toLowerCase().endsWith(".xlsx"))) {
                return null;
            }
            ExcelReader excelReader = EasyExcel.read(inputStream, clazz, excelListener).build();
            inputStream.close();
            return excelReader;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


}
